package com.mspbots.ticketai.graderule;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mspbots.ticketai.GradeRuleInterceptorAdapter;
import com.mspbots.ticketai.model.Ticket;
import com.mspbots.ticketai.model.TicketRule;
import lombok.Data;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Log4j2
@Service(value = "IN_WATCH_LIST_POINT_RULE")
public class InWatchListRuleInterceptor extends GradeRuleInterceptorAdapter {

    private List<InWatchListParam> params;

    @Override
    public void prepare(TicketRule rule) {
        params = this.objectMapper.convertValue(rule.getParams(), new TypeReference<>() {
        });
    }

    @Override
    public void process(Ticket ticket) {
        AtomicInteger order = new AtomicInteger();
        ObjectNode orderDetailNode = ticket.getOrderDetail() == null ? this.objectMapper.createObjectNode() : ticket.getOrderDetail().deepCopy();
        ObjectNode itemsNode = this.objectMapper.createObjectNode();
        if (!CollectionUtils.isEmpty(ticket.getCompanyWatchList()) && ticket.getCompanyName() != null) {
            params.stream().filter(p -> p.isSelected())
                    .forEach(item ->
                            ticket.getCompanyWatchList().stream()
                                    .filter(co -> co.getName().equalsIgnoreCase(ticket.getCompanyName()))
                                    .forEach(c -> order.addAndGet(item.getPoints()))
                    );
        }
        itemsNode.put("company", ticket.getCompanyName());
        itemsNode.put("point", order.get());
        orderDetailNode.set("companyWatch", itemsNode);
        ticket.setOrderDetail(orderDetailNode);
        ticket.setOrder(ticket.getOrder() + order.get());
    }

    @Data
    private static class InWatchListParam {
        private Integer points;
        private boolean selected;
        private Integer index;
        private String condition;
    }
}
